//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#include "Graphics/Resources/BitmapFont.h"
#include "Graphics/Resources/Font.inl.h"
#include "Graphics/Systems/GraphicsEngine.h"

namespace Engine
{
namespace Graphics
{
	
	struct BitmapFont::GlyphReader
	{
	// variables
	private:
		BitmapFont &	fnt;
	
	// methods
	public:
		GlyphReader (BitmapFont &fnt) : fnt(fnt)
		{}

		void ScaleChanged (const vec2 &scale) const
		{
		}

		float GetBaseLineTopMargin () const
		{
			return fnt._baseLineTopMargin;
		}

		bool Load (uint8 i) const
		{
			return i < fnt._glyphs.Count();
		}

		void SetMaterial (const BatchRenderPtr &br, const BatchMaterial &mtr) const
		{}

		IFont::Glyph const &	Get (uint i) const
		{
			return fnt._glyphs[i];
		}
	};


/*
=================================================
	constructor
=================================================
*/
	BitmapFont::BitmapFont (const EngineSubSystemsRef ess, EResource::type resType) :
		IFont( resType, ess ), _texture(ess),
		_baseLineTopMargin(0.0f), _height(0)
	{
	}
		
/*
=================================================
	destructor
=================================================
*/
	BitmapFont::~BitmapFont ()
	{}
	
/*
=================================================
	Draw
=================================================
*/
	void BitmapFont::Draw (const FontBatch &params, const vec2 &pos, uni_c_string text, bool scissor)
	{
		rect const &	view = ESS()->GetGraphicsEngine()->GetViewport()->ViewRect();

		Draw( params, rect( pos.x, view.bottom, view.right, pos.y ), text, scissor );
	}
	
/*
=================================================
	Draw
=================================================
*/
	void BitmapFont::Draw (const FontBatch &params, const rect &region, uni_c_string text, bool scissor)
	{
		BatchRenderPtr	br = ESS()->GetGraphicsEngine()->GetBatchRender();
		ViewportPtr		vp = ESS()->GetGraphicsEngine()->GetViewport();
		
		BatchMaterial	mtr = params.GetMaterial();

		mtr.ResetTextures();
		mtr.SetTexture( 0, GetTexture() );

		br->SetMaterial< FontRect2D >( mtr );

		GlyphReader	reader( *this );

		IFont::_Draw( vp, br, reader, params, region, text, scissor );
	}
	
/*
=================================================
	Draw
=================================================
*/
	void BitmapFont::Draw (const FontBatch &params, const vec2 &pos, const ext_string &text, bool scissor)
	{
		rect const &	view = ESS()->GetGraphicsEngine()->GetViewport()->ViewRect();

		Draw( params, rect( pos.x, view.bottom, view.right, pos.y ), text, scissor );
	}
	
/*
=================================================
	Draw
=================================================
*/
	void BitmapFont::Draw (const FontBatch &params, const rect &region, const ext_string &text, bool scissor)
	{
		BatchRenderPtr	br = ESS()->GetGraphicsEngine()->GetBatchRender();
		ViewportPtr		vp = ESS()->GetGraphicsEngine()->GetViewport();
		
		BatchMaterial	mtr = params.GetMaterial();

		mtr.ResetTextures();
		mtr.SetTexture( 0, GetTexture() );

		br->SetMaterial< FontRect2D >( mtr );

		GlyphReader	reader( *this );

		IFont::_Draw( vp, br, reader, params, region, text, scissor );
	}
	
/*
=================================================
	GetTextDimensions
=================================================
*/
	void BitmapFont::GetTextDimensions (const FontBatch &params, uni_c_string text, OUT vec2 &dim, OUT usize &lineLength)
	{
		ViewportPtr		vp = ESS()->GetGraphicsEngine()->GetViewport();
		
		GlyphReader		reader( *this );

		IFont::_GetTextDimensions( vp, reader, params, text, dim, lineLength );
	}
	
/*
=================================================
	GetTextDimensions
=================================================
*/
	void BitmapFont::GetFormattedText (const FontBatch &params, float maxLineWidth, const ext_string &text,
										const LocaleCharacters &localeChars, OUT ext_string &formattedText, OUT vec2 &dim)
	{
		ViewportPtr		vp = ESS()->GetGraphicsEngine()->GetViewport();
		
		GlyphReader		reader( *this );

		IFont::_GetFormattedText( vp, reader, maxLineWidth, params, text, localeChars, formattedText, dim );
	}

/*
=================================================
	New
=================================================
*/
	BitmapFontPtr	BitmapFont::New (const EngineSubSystemsRef ess)
	{
		return BaseObject::_New( new BitmapFont( ess ) );
	}
	
/*
=================================================
	GetDefaultLoadParams
=================================================
*/
	BitmapFont::BitmapFontLoadParams  BitmapFont::GetDefaultLoadParams ()
	{
		BitmapFontLoadParams	params;

		params.height	= 32;
		params.mipmaps	= true;

		return params;
	}
	
/*
=================================================
	GetDefaultScale
=================================================
*/
	float BitmapFont::GetDefaultScale () const
	{
		ViewportPtr	vp = ESS()->GetGraphicsEngine()->GetViewport();

		return IFont::_CalcDefaultScale( vp, GetHeightInPixels() );
	}
	
/*
=================================================
	SwapData
=================================================
*/
	bool BitmapFont::SwapData (const ResourcePtr &res)
	{
		CHECK_ERR( Resource::SwapData( res ) );

		BitmapFont * bf = (BitmapFont *) res.ptr();

		_swap( this->_glyphs,				bf->_glyphs );
		_swap( this->_baseLineTopMargin,	bf->_baseLineTopMargin );
		_swap( this->_height,				bf->_height );

		this->_texture.SwapData( &bf->_texture );

		return true;
	}
		
/*
=================================================
	IsLoadedWithParams
=================================================
*/
	bool BitmapFont::IsLoadedWithParams (const ResLoadParams &params) const
	{
		return	Resource::IsLoadedWithParams( params ) and
				_height == params.To< BitmapFontLoadParams >().height;
	}

/*
=================================================
	IsValid
=================================================
*/
	bool BitmapFont::IsValid () const
	{
		return _texture.IsValid() and not _glyphs.Empty();
	}

/*
=================================================
	IsLoadedWithParams
=================================================
*/
	void BitmapFont::_CalcMemSize ()
	{
		_memSize = _glyphs.Size() + _texture.GetMemSize();
	}


}	// Graphics
}	// Engine